home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SRSample.c
-
- Contains: Sample code illustrating basic use of the
- Speech Recognition Manager.
-
- Written by: Arlo Reeves & Matt Pallakoff, Apple Computer, Inc.
- */
-
- #include "SpeechRecognition.h"
- #include <Types.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <OSUtils.h>
- #include <ToolUtils.h>
- #include <Menus.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Resources.h>
- #include <Files.h>
- #include <Errors.h>
- #include <AppleEvents.h>
- #include <Gestalt.h>
- #include <string.h>
-
- /* 'DITL' ID's for main dialog */
-
- enum {
- kQuitButton = 1,
- kWhatYouCanSayStTx,
- kGrammarStTx,
- kWhatWasHeardStTx,
- kResultTextStTx
- };
-
- /* constants */
-
- enum {
- kDialogResID = 128,
-
- kTopLMRefcon = 100,
- kHelloRefCon = 0, /* distinguishes between different results */
- kGoodbyeRefCon,
- kWhatTimeIsItRefCon,
- kCompanyRefCon,
- kAppleRefCon = 0,
- kNetscapeRefCon,
- kCocaColaRefCon,
-
- kErrorAlertResID = 129,
- kErrStringType = 'Estr',
- kInternalError = 100,
- kBadSRMVersion
- };
-
- /* globals */
- DialogPtr gDialog = NULL;
-
- SRRecognitionSystem gRecognitionSystem = NULL; /* our speech recognition system */
- SRRecognizer gRecognizer = NULL; /* our recognizer */
- SRLanguageModel gTopLanguageModel = NULL; /* our language model - what we're listening for */
- AEEventHandlerUPP gAERoutineDescriptor = NULL; /* our AppleEvent routine descriptor */
-
- /* prototypes */
-
- void main(void);
- OSErr DoMainEventLoop (void);
- Boolean HasValidSpeechRecognitionVersion (void);
- OSErr InitSpeechRecognition (void);
- OSErr TerminateSpeechRecognition (void);
- OSErr BuildLanguageModel (void);
- OSErr AddFancierLanguageModel (SRLanguageModel baseLM);
- pascal OSErr HandleRecognitionDoneAE (AppleEvent *theAEevt, AppleEvent *reply, long refcon);
- OSErr ProcessRecognitionResult (SRRecognitionResult result, SRRecognizer recognizer);
- OSErr ProcessFancierLanguageModel (SRPath resultPath, SRRecognizer recognizer);
- OSErr DisplayRecognizedText (SRRecognitionResult result);
- void ErrorAlert (OSErr macErr);
- OSErr DisableStockPath ();
- OSErr RefillCompanyLM ();
- OSErr SaveTopLanguageModel ();
-
- /* main entry point
-
- Remember, this application is meant to show you how to use the
- Speech Recognition Manager, not to show good human interface programming.
- The following code to manage the dialog is not meant to be a good example
- of application design.
- */
-
- void main(void)
- {
- OSErr status = noErr;
-
- /* initialize the world */
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- MaxApplZone();
-
- status = InitSpeechRecognition ();
-
- if (!status) {
- status = BuildLanguageModel ();
-
- if (!status)
- status = SRSetLanguageModel (gRecognizer, gTopLanguageModel);
-
- if (!status) {
- status = SRStartListening (gRecognizer);
-
- if (!status) status = DoMainEventLoop (); /* ignore status */
-
- status = SRStopListening (gRecognizer);
- }
-
- TerminateSpeechRecognition (); /* ignore status */
- }
-
- if (status)
- ErrorAlert (status);
- }
-
-
- /* DoMainEventLoop
-
- Brings up our simple dialog. Then processes the events as they come.
- */
-
- OSErr DoMainEventLoop (void)
- {
- OSErr status = noErr;
- GrafPtr oldPort;
-
- /* setup main window */
- GetPort (&oldPort);
-
- gDialog = GetNewDialog (kDialogResID, nil, (WindowPtr) -1);
- if (gDialog) {
- Boolean done = false;
- SetPort (gDialog);
- ShowWindow (gDialog);
-
- /* main event loop */
- while (!done) {
- DialogPtr dlog;
- EventRecord event;
-
- if (WaitNextEvent (everyEvent, &event, 10, NULL)) {
-
- /* if a dialog event, do the dialog thing... */
- if (IsDialogEvent (&event)) {
- short itemHit;
-
- if (DialogSelect (&event, &dlog, &itemHit)) {
- switch (itemHit) {
- case kQuitButton:
- done = true;
- break;
- }
- }
- }
-
- /* ...otherwise it's a normal event */
- else {
- switch (event.what) {
- case nullEvent:
- case mouseDown:
- {
- short partCode;
- switch (partCode = FindWindow (event.where, &dlog)) {
- case inDrag:
- DragWindow (dlog, event.where, &qd.screenBits.bounds);
- break;
- }
- }
- break;
- case kHighLevelEvent:
- AEProcessAppleEvent (&event);
- break;
- case keyDown:
- case autoKey:
- case diskEvt:
- default:
- break;
- }
- }
- }
- }
- DisposeDialog (gDialog);
- }
- else status = kInternalError;
-
- SetPort(oldPort);
-
- return status;
- }
-
- /* HasValidSpeechRecognitionVersion
-
- This routine checks the Speech Recognition Manager version and makes sure the version
- is greater than or equal to the version needed for this program to run. Only Speech
- Recognition Manager versions >= 1.5 adhere to the publicly defined API.
- */
-
- Boolean HasValidSpeechRecognitionVersion (void)
- {
- OSErr status;
- long theVersion;
- Boolean validVersion = false;
- const unsigned long kMinimumRequiredSRMVersion = 0x00000150;
-
- status = Gestalt (gestaltSpeechRecognitionVersion, &theVersion);
-
- if (!status)
- if (theVersion >= kMinimumRequiredSRMVersion)
- validVersion = true;
-
- return validVersion;
- }
-
- /* InitSpeechRecognition
-
- If the Speech Recognition Manager version is valid, this routine opens a recognition system
- and a recognizer, setting the kSRFeedbackAndListeningModes property to kSRHasFeedbackHasListenModes
- so that SRSample will have a Speech Recognition feedback window.
- */
-
- OSErr InitSpeechRecognition (void)
- {
- OSErr status = kBadSRMVersion;
-
- /* Ensure that the Speech Recognition Mgr is available. */
- if (HasValidSpeechRecognitionVersion ()) {
-
- /* Open the default recognition system. */
- status = SROpenRecognitionSystem (&gRecognitionSystem, kSRDefaultRecognitionSystemID);
-
- /* Use standard feedback window and listening modes. */
- if (!status) {
- short feedbackNeeded = kSRHasFeedbackHasListenModes;
-
- status = SRSetProperty (gRecognitionSystem, kSRFeedbackAndListeningModes, &feedbackNeeded, sizeof(feedbackNeeded));
- }
-
- /* Create a new recognizer */
- if (!status)
- status = SRNewRecognizer (gRecognitionSystem, &gRecognizer, kSRDefaultSpeechSource);
-
- /* install our Apple Event handler for recognition results */
- if (!status) {
- status = memFullErr;
- gAERoutineDescriptor = NewAEEventHandlerProc (HandleRecognitionDoneAE);
-
- if (gAERoutineDescriptor)
- status = AEInstallEventHandler (kAESpeechSuite, kAESpeechDone, gAERoutineDescriptor, 0, false);
- }
- }
-
- return status;
- }
-
-
- /* TerminateSpeechRecognition
-
- Close down the Recognizer and RecognitionSystem allocated in InitSpeechRecognition.
- Stop listening before releasing the recognizer just for thoroughness (it's harmless
- if we aren't listening).
-
- status is ignored througout.
- */
-
- OSErr TerminateSpeechRecognition (void)
- {
- OSErr status = noErr;
-
- /* if we have a top level language model, release it */
- if (gTopLanguageModel) {
- status = SRReleaseObject (gTopLanguageModel); /* ignore status */
- gTopLanguageModel = NULL;
- }
-
- /* if we have a recognizer, release it */
- if (gRecognizer) {
- status = SRStopListening (gRecognizer);
- status = SRReleaseObject (gRecognizer);
- gRecognizer = NULL;
- }
-
- /* if we have a recognition system, close it */
- if (gRecognitionSystem) {
- status = SRCloseRecognitionSystem (gRecognitionSystem);
- gRecognitionSystem = NULL;
- }
-
- /* remove our AppleEvent handler and dispose of the handler's routine descriptor */
- if (gAERoutineDescriptor) {
- status = AERemoveEventHandler (kAESpeechSuite, kAESpeechDone, gAERoutineDescriptor, false);
- DisposeRoutineDescriptor (gAERoutineDescriptor);
- gAERoutineDescriptor = NULL;
- }
-
- return status;
- }
-
- /* BuildLanguageModel
-
- Allocates and builds gTopLanguageModel to be
-
- Hello or
- Goodbye or
- What time is it?
-
- Using the simplest technique, SRAddText. It then augments this simple language
- model with a fancier one by calling AddFancierLanguageModel.
- */
-
- OSErr BuildLanguageModel (void)
- {
- OSErr status = noErr;
- const char kLMName[] = "<Top LM>";
-
- /* first, allocate the language model, storing it in gTopLanguageModel */
- status = SRNewLanguageModel (gRecognitionSystem, &gTopLanguageModel, kLMName, strlen (kLMName));
-
- if (!status) {
- long refcon = kTopLMRefcon;
-
- /* set the refcon of our top language model so that when we process our recognition */
- /* result we will be able to distinguish it from the rejection word, "???" */
- status = SRSetProperty (gTopLanguageModel, kSRRefCon, &refcon, sizeof (refcon));
-
- if (!status) {
- const char *kSimpleStr[] = { "Hello", "Goodbye", "What time is it?", NULL };
- char **currentStr = (char **) kSimpleStr;
- long refcon = kHelloRefCon;
-
- /* Add each of the strings in kSimpleStr to the language model, and set the refcon to */
- /* the index of the string in the kSimpleStr array. Note that SRAddText is a shortcut */
- /* for calling SRNewPhrase, SRAddLanguageObject, and SRReleaseObject in succession */
-
- while (*currentStr && !status) {
- status = SRAddText (gTopLanguageModel, *currentStr, strlen (*currentStr), refcon++);
- ++currentStr;
- }
-
- /* now augment this simple language model with a fancier one */
- if (!status)
- status = AddFancierLanguageModel (gTopLanguageModel);
- }
- }
-
- return status;
- }
-
- /* AddFancierLanguageModel
-
- Augment the language model built in BuildSimpleLanguageModel to have a fourth
- phrase which includes an embedded language model and an optional word:
-
- Tell me the price of <company> [stock]
-
- where
-
- <company> = Apple | Netscape | Coca Cola
-
- is the embedded language model and [stock] indicates that the word 'stock'
- is optional.
- */
-
- OSErr AddFancierLanguageModel (SRLanguageModel baseLM)
- {
- OSErr status = noErr;
-
- /* First create a new SRPath, to which we will add the phrase "Tell me the price of" */
- /* the language model "<company>" and the word "stock". We'll then add this path to */
- /* the baseLM */
-
- SRPath stockPath;
-
- status = SRNewPath (gRecognitionSystem, &stockPath);
-
- if (!status) {
- const char kWhatString[] = "Tell me the price of";
- SRPhrase whatPhrase = NULL;
- SRLanguageModel companyLM = NULL;
- SRWord stockWord = NULL;
- long refcon = kCompanyRefCon;
-
- /* set the refcon now to help us distinguish what was said later */
- status = SRSetProperty (stockPath, kSRRefCon, &refcon, sizeof (refcon));
-
- if (!status) {
- /* allocate the phrase "Tell me the price of" */
- status = SRNewPhrase (gRecognitionSystem, &whatPhrase, kWhatString, strlen (kWhatString));
-
- /* add the whatPhrase to the stockPath */
- if (!status) {
- status = SRAddLanguageObject (stockPath, whatPhrase);
-
- /* once added, the stockPath retains a reference to the whatPhrase */
- /* so we can release the whatPhrase now */
- if (!status) {
- status = SRReleaseObject (whatPhrase);
- whatPhrase = NULL;
- }
- }
- }
-
- /* create the embedded language model <company> and add it to the stockPath */
- if (!status) {
- const char kCompanyLMName[] = "<company LM>";
-
- /* allocate the embedded language model '<company>' */
- status = SRNewLanguageModel (gRecognitionSystem, &companyLM, kCompanyLMName, strlen (kCompanyLMName));
-
- if (!status) {
- const char *kCompanyNames[] = { "Apple", "Netscape", "Pepsi", NULL };
- char **companyName = (char **) kCompanyNames;
- long refcon = kAppleRefCon;
-
- /* add the compnay names to the language model '<company>' */
- while (*companyName && !status) {
- status = SRAddText (companyLM, *companyName, strlen (*companyName), refcon++);
- ++companyName;
- }
-
- /* add the company language model to the stockPath... */
- if (!status) {
- status = SRAddLanguageObject (stockPath, companyLM);
-
- /* ... and release it since it is now 'owned' by the stockPath */
- if (!status) {
- status = SRReleaseObject (companyLM);
- companyLM = NULL;
- }
- }
- }
- }
-
- /* create the word 'stock', make it optional and add it to the stockPath */
- if (!status) {
- const char kStockWord[] = "stock";
-
- /* allocated the word */
- status = SRNewWord (gRecognitionSystem, &stockWord, kStockWord, strlen (kStockWord));
-
- if (!status) {
- Boolean wantOptional = true;
-
- /* make it optional by setting it's kSROptional property to true */
- status = SRSetProperty (stockWord, kSROptional, &wantOptional, sizeof (wantOptional));
-
- /* add it to the stockPath */
- if (!status) {
- status = SRAddLanguageObject (stockPath, stockWord);
-
- /* ... and release our reference to it */
- if (!status) {
- status = SRReleaseObject (stockWord);
- stockWord = NULL;
- }
- }
- }
- }
-
-
- /* add the stock path to the baseLM and we're done */
- if (!status) {
- status = SRAddLanguageObject (baseLM, stockPath);
-
- /* and release our reference to the path now that we're done with it */
- if (!status) {
- status = SRReleaseObject (stockPath);
- stockPath = NULL;
- }
- }
-
- /* if we had any problems along the way, clean up here */
- if (status) {
- if (whatPhrase) SRReleaseObject (whatPhrase); /* status ignored */
- if (companyLM) SRReleaseObject (companyLM);
- if (stockWord) SRReleaseObject (stockWord);
- if (stockPath) SRReleaseObject (stockPath);
- }
- }
-
- return status;
- }
-
-
- /* HandleRecognitionDoneAE
-
- This is our AppleEvent handler for the kSRRecognitionDone AppleEvent.
- It extracts the recognition status code, and if there's something to
- process, it extracts the recognizer and recognition result objects from
- the AppleEvent. These are then process in ProcessRecognitionResult
- */
-
- pascal OSErr HandleRecognitionDoneAE (AppleEvent *theAEevt, AppleEvent *reply, long refcon)
- {
- OSErr recognitionStatus = 0, status;
- long actualSize;
- DescType actualType;
-
- /* Get recognition result status. */
- status = AEGetParamPtr (theAEevt, keySRSpeechStatus, typeShortInteger, &actualType, (Ptr) &recognitionStatus, sizeof (recognitionStatus), &actualSize);
-
- /* Get the SRRecognizer */
- if (!status && !recognitionStatus) {
- SRRecognizer recognizer;
- status = AEGetParamPtr (theAEevt, keySRRecognizer, typeSRRecognizer, &actualType, (Ptr) &recognizer, sizeof (recognizer), &actualSize);
-
- /* Get the SRRecognitionResult */
- if (!status) {
- SRRecognitionResult recResult;
- status = AEGetParamPtr (theAEevt, keySRSpeechResult, typeSRSpeechResult, &actualType, (Ptr) &recResult, sizeof (recResult), &actualSize);
-
- /* extract the language model from the result */
- if (!status) {
- SRLanguageModel resultLM;
- long propertySize = sizeof (resultLM);
-
- /* first get the text from the result and display it in our dialog */
- status = DisplayRecognizedText (recResult);
-
- /* get the language model out of the recognition result */
- if (!status)
- status = SRGetProperty (recResult, kSRLanguageModelFormat, &resultLM, &propertySize);
-
- /* process the language model */
- if (!status) {
- status = ProcessRecognitionResult (resultLM, recognizer);
-
- /* what we SRGot… we must SRRelease…! */
- SRReleaseObject (resultLM);
- }
- /* Also release the recognition result */
- SRReleaseObject (recResult);
- }
- }
- }
-
- /* if recognition went fine, how about the processing? */
- return recognitionStatus ? recognitionStatus : status;
- }
-
- /* ProcessRecognitionResult
-
- Process the recogition result here. Get the kSRLMFormat (SRLangugaeModel) property from
- the recogntion result; it is a SRLanguageModel object whose contents correspond to the words
- that were heard. By inspecting the refcon of the first item in this language model, we
- the first item contained in this
- */
-
- OSErr ProcessRecognitionResult (SRLanguageModel resultLM, SRRecognizer recognizer)
- {
- OSErr status = noErr;
-
- if (resultLM && recognizer) {
- long refcon;
- long propertySize = sizeof (refcon);
-
- status = SRGetProperty (resultLM, kSRRefCon, &refcon, &propertySize);
-
- /* is the resultLM a subset of our top language model or is it the rejection word, "???" ? */
- if (!status && refcon == kTopLMRefcon) {
- SRLanguageObject languageObject;
- propertySize = sizeof (languageObject);
-
- /* The resultLM contains either an SRPath or an SRPhrase. The SRPhrases in gTopLanguageModel */
- /* were created by the SRAddText calls in BuildLanguageModel. The SRPath in */
- /* gTopLanguageModel was created in AddFancierLanguageModel. We use the refcon property */
- /* we set in our language model building routines to distinguish between the results */
-
- /* We expect our result language model to contain only 1 item, a phrase or a path; get it */
- status = SRGetIndexedItem (resultLM, &languageObject, 0);
-
- if (!status) {
- long refcon;
- propertySize = sizeof (refcon);
-
- /* get the refcon of the object at the root of our language model */
- status = SRGetProperty (languageObject, kSRRefCon, &refcon, &propertySize);
-
- if (!status) switch (refcon) {
- case kHelloRefCon:
- case kGoodbyeRefCon:
- case kWhatTimeIsItRefCon:
- {
- const char *kResponses[] =
- { "Hi There!",
- "Don't leave now!",
- "It's time to use the Speech Recognition Manager!"
- };
- /* speak and display our response using the feedback character. Use */
- /* the refcon as an index into our response array */
- status = SRSpeakAndDrawText (recognizer, kResponses[refcon], strlen (kResponses[refcon]));
- }
- break;
- case kCompanyRefCon:
- status = ProcessFancierLanguageModel (languageObject, recognizer);
- break;
- }
-
- /* always SRRelease… what we SRGot… */
- status = SRReleaseObject (languageObject);
- }
- }
- }
-
- return status;
- }
-
- /* ProcessFancierLanguageModel
-
- The SRPath contains 2 or 3 items: a phrase "Tell me the price of", an embedded
- language model <company> and perhaps the word 'stock'. Our response depends only
- on the name of the company uttered. The company name will always be the second
- item in the path, so we access it directly and respond appropriately.
- */
-
- OSErr ProcessFancierLanguageModel (SRPath resultPath, SRRecognizer recognizer)
- {
- OSErr status = noErr;
-
- if (resultPath && recognizer) {
- SRLanguageModel companyLM;
-
- /* get the second item in the path — it's the company language model */
- status = SRGetIndexedItem (resultPath, &companyLM, 1);
-
- if (!status && companyLM) {
- SRPhrase companyName;
-
- /* the company language model will contain only 1 phrase; get it. */
- status = SRGetIndexedItem (companyLM, &companyName, 0);
-
- if (!status) {
- long refcon;
- long propertySize = sizeof (refcon);
-
- /* get the refcon from the company name; it's our index into the response array */
- status = SRGetProperty (companyName, kSRRefCon, &refcon, &propertySize);
-
- if (!status) {
- const char *kResponses[] = { "Apple stock is priced to move!",
- "Netscape is trading at fifty dollars.",
- "Why would you want to know that?"
- };
- status = SRSpeakAndDrawText (recognizer, kResponses[refcon], strlen (kResponses[refcon]));
- }
-
- /* what we SRGot… we must SRRelease… */
- status = SRReleaseObject (companyName);
- }
-
- status = SRReleaseObject (companyLM);
- }
- }
-
- return status;
- }
-
-
- /* DisplayRecognizedText
-
- This routine extracts the text from the recognition result, whatever that text
- might be, and displays it in our dialog.
- */
-
- OSErr DisplayRecognizedText (SRRecognitionResult result)
- {
- OSErr status = noErr;
-
- /* first get the text from the result and display it in our dialog */
- if (result) {
- Str255 resultText;
- long resultTextSize = sizeof (resultText) - 1;
-
- status = SRGetProperty (result, kSRTEXTFormat, &resultText[1], &resultTextSize);
-
- if (!status) {
- short iType;
- Handle iHandle;
- Rect iRect;
-
- /* create pascal string of result text */
- resultText[0] = (char) resultTextSize;
-
- GetDialogItem (gDialog, kResultTextStTx, &iType, &iHandle, &iRect);
- SetDialogItemText (iHandle, resultText); /* this handles redraw */
- }
- }
-
- return status;
- }
-
-
- /* ErrorAlert
-
- Looks for an 'Estr' resource with ID macErr and provides a default error
- string if none is found, then posts an alert forcing the user to quit.
- */
-
- void ErrorAlert (OSErr macErr)
- {
- StringHandle errMsg;
- Str255 errNum;
- short itemHit;
-
- errMsg = (StringHandle) GetResource (kErrStringType, macErr);
- if (!errMsg)
- errMsg = (StringHandle) GetResource (kErrStringType, kInternalError);
- NumToString (macErr, errNum);
- HLock ((Handle) errMsg);
- ParamText (*errMsg, errNum, NULL, NULL);
- InitCursor ();
- itemHit = StopAlert (kErrorAlertResID, NULL);
- HUnlock ((Handle) errMsg);
- ReleaseResource ((Handle) errMsg);
- }
-
-
- /* DisableStockPath
- disable the stockPath part of the gTopLanguageModel built in AddFancierLanguageModel.
- */
-
- OSErr DisableStockPath ()
- {
- /* The stock path is the 4th item in this LM */
- SRPath stockPath;
- OSErr status = SRGetIndexedItem (gTopLanguageModel, &stockPath, 3);
-
- if (!status) {
- Boolean enabled = false;
-
- status = SRSetProperty (stockPath, kSREnabled, &enabled, sizeof (enabled));
-
- SRReleaseObject (stockPath); /* ignore status */
- }
-
- return status;
- }
-
- /*
- RefillCompanyLM
-
- Replace the contents of the <company> language model with different company names.
- */
-
- OSErr RefillCompanyLM ()
- {
- /* The stock path is the 4th item in this LM */
- SRPath stockPath;
- OSErr status = SRGetIndexedItem (gTopLanguageModel, &stockPath, 3);
-
- if (!status) {
- /* empty & refill the embedded <company> language model. */
- /* the companyLM is the second item in the stockPath */
- SRLanguageModel companyLM;
- OSErr status = SRGetIndexedItem (stockPath, &companyLM, 1);
-
- if (!status) {
- /* this releases each phrase in the company language model */
- status = SREmptyLanguageObject (companyLM);
-
- /* now rebuild the company language model with new companies */
- if (!status) {
- const char *kNewCompanies[] = { "I B M", "Motorola", "Coca Cola", NULL };
- char **company = (char **) kNewCompanies;
- long refcon = 0;
-
- while (*company && !status) {
- status = SRAddText (companyLM, *company, strlen (*company), refcon++);
- ++company;
- }
- }
- }
- status = SRReleaseObject (stockPath); /* SRRelease… what we SRGot… */
- }
-
- return status;
- }
-
- /* SaveTopLanguageModel
-
- Save the gTopLanguageModel to the current resource file. Note that
- in this case that's the resource fork of this application and is
- therefore unadvisable behavior.
- */
-
- OSErr SaveTopLanguageModel ()
- {
- /* allocate a Handle of size 0 to store our language model in; */
- /* SRPutLanguageObjectIntoHandle will resize it as needed */
- Handle lmHandle = NewHandle (0);
- OSErr status = MemError ();
-
- if (!status) {
- status = SRPutLanguageObjectIntoHandle (gTopLanguageModel, lmHandle);
-
- if (!status) {
- /* save the language model as a resource in the current */
- /* resource file. Pick a reasonable resource type & ID */
- AddResource (lmHandle, 'LMDL', 100, "\pTop Language Model");
-
- /* make sure it gets written to disk */
- if (!(status = ResError ()))
- WriteResource (lmHandle);
- }
-
- DisposeHandle (lmHandle);
- }
-
- return status;
- }
-
-
-